/**
 * Created by 40637 on 2016/11/29.
 */

var d3 = window.d3;

var chart = d3.select(".chart");

// 设置SVG内部的MARGIN
var MARGIN = {
    top: 15,
    bottom: 20,
    left: 50,
    right: 20
};

// 根据内部MARGIN计算width和height
var magicNumber_2 = 1000;
var width = magicNumber_2 - MARGIN.left - MARGIN.right;
var magicNumber_1 = 600;
var height = magicNumber_1 - MARGIN.top - MARGIN.bottom;

// 准备坐标轴
var radius = Math.min(width, height) / 2;
var x = d3.scaleLog().rangeRound([0, radius]);
var pho = d3.scaleLinear();

// 角度化弧度
function degreeToRadian(degree) {
    return (degree / 180 * Math.PI);
}

// 弧度化角度
function radianToDegree(radian) {
    return (radian / Math.PI * 180);
}

// 计算极坐标
function polarCoord(cartesian) {
    cartesian.y = cartesian[1];
    cartesian.x = cartesian[0];
    var pho = Math.atan2(cartesian.y, cartesian.x);
    if (pho < 0){
        pho += 2 * Math.PI;
    }
    return {
        r: Math.sqrt(cartesian.x * cartesian.x + cartesian.y * cartesian.y),
        p: pho
    };
}

// 计算直角坐标
function cartsCoord(polar) {
    return {
        x: polar.r * Math.cos(polar.p),
        y: polar.r * Math.sin(polar.p)
    };
}

// 用于构建一个子模块，实现margin
var g = chart.append("g")
    .attr("transform", "translate(" + MARGIN.left + "," + MARGIN.top + ")");

// 建立抗生素种类和颜色之间的映射关系
var antibiotics = [
    {
        name:"Penicilin",
        color: "red"
    }, {
        name:"Streptomycin",
        color: "green"
    }, {
        name:"Neomycin",
        color: "blue"
    }
];

// 排序关键字
sortedKeys = ["Bacteria","Penicilin","Streptomycin","Neomycin","Gram Staining"];
sortedKeyID = 4;

// 加载CSV数据
var rawdata;
var ax, apho;
// d3.csv(url[[, row], callback])
d3.csv("a1-burtin.csv", function(d){
    d.Penicilin = +d.Penicilin;
    d.Streptomycin = +d.Streptomycin;
    d.Neomycin = +d.Neomycin;
    return d;
}, function (error, data) {
    var i, j;

    data = data.sort(function (a, b) {
        var A, B;
        if (sortedKeyID == 0 || sortedKeyID == 4) {
            A = a[sortedKeys[sortedKeyID]].toUpperCase();
            B = b[sortedKeys[sortedKeyID]].toUpperCase();
        } else {
            A = a[sortedKeys[sortedKeyID]];
            B = b[sortedKeys[sortedKeyID]];
        }
        var ret;
        if (A < B)
            ret = -1;
        else if (A > B)
            ret = 1;
        else
            ret = 0;
        return ret;
    });

    // 为了调试方便
    rawdata = data;

    if (error)
        throw error;

    // 如果成功读取，所有的数据应该在rawdata和data内
    x.domain([d3.min(data, function(d) {return Math.min(d.Penicilin, d.Neomycin, d.Streptomycin) / 10;}),
        d3.max(data, function(d) {return Math.max(d.Penicilin, d.Neomycin, d.Streptomycin) * 10;})]);
    var xAxis = d3.axisBottom(x);
    xAxis.tickFormat(d3.format(",.2f")).ticks(5);
    pho.domain([0, data.length - 1]).range([0, 2 * Math.PI * ( 1 - 1 / data.length)]);

    // 为了调试方便
    ax = x; apho = pho;

    // 绘制参考圆
    var circleSet = g.append("g");
    for (i=-3;i<4;i++) {
        circleSet.append("circle")
            .attr("class", "refCircle")
            .attr("cx", radius)
            .attr("cy", radius)
            .attr("r", x(Math.pow(10, i)));
    }

    // 大量绘制辅助线
    var magicNumber_0 = 14;
    var polar = {
        r: 0,
        p: 0
    }, carts = {
        x: 0,
        y: 0
    };
    for (i = 0;i<data.length; i++) {
        polar.p = pho(i);
        polar.r = radius;
        carts = cartsCoord(polar);
        g.append("line")
            .attr("class", "refHLine")
            .attr("x1", radius)
            .attr("y1", radius)
            .attr("x2", radius + carts.x)
            .attr("y2", radius + carts.y);
    }
    //.attr("y2", function(d, i) {return y(d.Bacteria);});

    // 在水平方向上绘制坐标轴
    g.append("g")
        .attr("class", "axis axis--x")
        .attr("transform", "translate(" + radius + "," + radius + ")")
        .call(xAxis);

    // 绘制原点
    g.append("g")
        .append("circle")
        .attr("class", "originalPoint")
        .attr("cx", radius)
        .attr("cy", radius);

    function gramStaining(data) {
        var ret;
        if (data["Gram Staining"]) {
            ret = "circle";
        } else {
            ret = "rect";
        }
        return ret;
    }

    // 绘制最小值连成的多边形，choice==0
    // 绘制各种抗生素的多边形，choice==1,2,3
    var minPolar, minArr = "";
    var choice=0;
    switch(choice) {
        case 0:
            for (i=0;i<data.length;i++) {
                minPolar = {
                    r: 100000,
                    p: 0
                };
                for (j = 0; j < antibiotics.length; j++) {
                    polar.r = x(data[i][antibiotics[j].name]);
                    polar.p = 2 * Math.PI * i / data.length;
                    if (polar.r < minPolar.r) {
                        minPolar.r = polar.r;
                        minPolar.p = polar.p;
                    }
                }
                carts = cartsCoord(minPolar);
                minArr += "" + (radius + carts.x) + "," + (radius + carts.y) + " ";
            }
            break;
        default:
            for (i=0;i<data.length;i++) {
                minPolar = {
                    r: 100000,
                    p: 0
                };
                j = choice - 1;
                polar.r = x(data[i][antibiotics[j].name]);
                polar.p = 2 * Math.PI * i / data.length;
                if (polar.r < minPolar.r) {
                    minPolar.r = polar.r;
                    minPolar.p = polar.p;
                }
                carts = cartsCoord(minPolar);
                minArr += "" + (radius + carts.x) + "," + (radius + carts.y) + " ";
            }
            break;
    }
    console.log(minArr);
    g.append("g")
        .append("polygon")
        .attr("class", "minialContour")
        .attr("points", minArr);

    var shape;
    for (i=0;i<data.length;i++) {
        if (data[i]["Gram Staining"] === "positive") {
            shape = "circle";
            for (j = 0;j < antibiotics.length;j++) {
                polar.r = x(data[i][antibiotics[j].name]);
                polar.p = 2 * Math.PI * i / data.length;
                carts = cartsCoord(polar);
                g.append(shape)
                    .attr("class", (shape + "Point"))
                    .attr("cx", radius + carts.x)
                    .attr("cy", radius + carts.y)
                    .attr("fill", antibiotics[j].color);
            }
        } else {
            shape = "rect";
            for (j = 0;j < antibiotics.length;j++) {
                polar.r = x(data[i][antibiotics[j].name]);
                polar.p = 2 * Math.PI * i / data.length;
                carts = cartsCoord(polar);
                g.append(shape)
                    .attr("class", (shape + "Point"))
                    .attr("x", radius + carts.x - 7)
                    .attr("y", radius + carts.y - 7)
                    .attr("width", 14)
                    .attr("height", 14)
                    .attr("fill", antibiotics[j].color);
            }
        }
    }

    // 循环绘制细菌名
    var magicNumber_3 = 5;
    for (i = 0;i<data.length;i++) {
        polar.r = radius + magicNumber_3;
        polar.p = 2 * Math.PI * i / data.length;
        carts = cartsCoord(polar);
        g.append('text')
            .attr("class", "bacteriaText")
            .attr("x", radius + carts.x)
            .attr("y", radius + carts.y)
            .text(data[i]["Bacteria"]);
    }

    final();
});

// 加载CSV文件并且完成绘制之后调用
function final() {
    // 添加标题
    var titleText = chart.append("text")
        .attr("class", "titleText")
        .attr("x", 580)
        .attr("y", 58)
        .text("图3 按照" + sortedKeys[sortedKeyID] + "排序的散点图");

    // 添加纵轴标记
    var yText_x = 40,
        yText_y = 330;
    var yText = chart.append("text")
        .attr("class", "axisText")
        .attr("x", yText_x)
        .attr("y", yText_y)
        .attr("transform", "rotate(-90 " + yText_x + "," + yText_y + ")")
        .text("Bacteria");

    // 添加横轴标记
    var xText = chart.append("text")
        .attr("class", "axisText")
        .attr("transform", "translate(590,330)")
        .text("Minimum inhibitory concentration (LIC)");

    // 添加显示标签
    var label_height = 150,
        label_width = 140;
    var label_x = 760,
        label_y = 120;
    var labelBox = chart.append("g")
        .attr("transform", "translate(" + label_x + "," + label_y + ")");
    var i;
    labelBox.append("rect")
        .attr("class", "labelFrame")
        .attr("height", label_height)
        .attr("width", label_width);
    // 循环设置图例标签
    for (i = 0;i<antibiotics.length; i++) {
        labelBox.append("circle")
            .attr("class", "circlePoint")
            .attr("fill", antibiotics[i].color)
            .attr("cx", 14)
            .attr("cy", 14 + i * 30);
        labelBox.append("rect")
            .attr("class", "rectPoint")
            .attr("fill", antibiotics[i].color)
            .attr("x", 34 - 7)
            .attr("y", 14 + i * 30 - 7)
            .attr("width", 14)
            .attr("height", 14);
        labelBox.append("text")
            .attr("class", "labelText")
            .attr("x", 48)
            .attr("y", 18 + i * 30)
            .text(antibiotics[i].name);
    }
    labelBox.append("circle")
        .attr("class", "circlePoint")
        .attr("fill", "black")
        .attr("cx", 14)
        .attr("cy", 14 + 3 * 30);
    labelBox.append("text")
        .attr("class", "labelText")
        .attr("x", 48)
        .attr("y", 18 + i * 30)
        .text("Gram Positive");
    labelBox.append("rect")
        .attr("class", "rectPoint")
        .attr("fill", "black")
        .attr("x", 34 - 7)
        .attr("y", 14 + 4 * 30 - 7)
        .attr("width", 14)
        .attr("height", 14);
    labelBox.append("text")
        .attr("class", "labelText")
        .attr("x", 48)
        .attr("y", 18 + 4 * 30)
        .text("Gram Negtive");
}




